/**
 * 爬虫引擎
 * 负责各模块之间数据交流
 */

const Item = require('./item')
const {Request} = require('./request')

class Crawler {
  constructor() {
  }

  /**
   * 开始调用爬虫爬取
   * 当有响应返时把 response 交给 spider 自己处理
   * @param spider
   */
  crawl(spider) {
    let requests = spider.startRequests()
    while (true) {
      let request = requests.next().value
      if (!request) break
      spider.downloader.down(request).then(response => {
        this.processResponse(response, spider)
      })
    }
  }

  /**
   * 处理下载器返回的 response
   * @param response
   * @param spider
   */
  processResponse(response, spider) {
    let callback = response.request.callback
    if (callback) {
      let parseResult = callback(response)
      this.processParseResult(parseResult, spider)
    } else {
      let parseResult = spider.parse(response)
      this.processParseResult(parseResult, spider)
    }
  }

  /**
   * 处理 spider 解析过的返回数据
   * 如果是 item 就给 pipelin，如果是 request 就给下载器
   * @param parseResult
   * @param spider
   */
  processParseResult(parseResult, spider) {
    while (true) {
      let result = parseResult.next().value
      if (!result) {
        break
      }
      if (result instanceof Item) {
        let item = spider.pipeline.catchItem(result, spider)
      } else if (result instanceof Request) {
        spider.downloader.down(result).then(response => {
          this.processResponse(response)
        })
      }
    }
  }
}

module.exports = Crawler